// 1. 环境配置和基础模块导入
require('dotenv').config();

// 2. 核心依赖导入
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
// const session = require('express-session');

// 3. 日志系统
const { getLogger, createRequestLogger, createErrorLogger, setGlobalLogLevel } = require('./src/logger');
const logger = getLogger('server');
const requestLogger = createRequestLogger({ logHeaders: true });
const errorLogger = createErrorLogger('server');

// 4. 配置和工具模块
const config = require('./config');
const { serverError } = require('./src/utils/response');
const requestIdMiddleware = require('./src/middlewares/requestIdMiddleware');

// 5. 控制器和服务
const authController = require('./src/controllers/authController');
const CodeService = require('./src/services/codeService'); // 编码服务

// 6. 连接和资源管理
const cacheService = require('./src/cache/cacheService');
const cacheConfig = config.cache;
const cacheType = cacheConfig.type || 'memory';

// 基础设施客户端
const { initializeDbPool, checkDatabaseConnection, closeDbPool } = require('./src/infra/dbClient');
const { initializeRedisClient, performHealthCheck: performRedisHealthCheck, closeConnection: closeRedis } = require('./src/infra/redisClient');

// 7. 管理器和调度器
const SSEManager = require('./src/utils/sseManager');
const scheduler = require('./src/infra/scheduler');

// 8. 应用实例
const app = express();

// 9. 全局配置
const isDev = process.env.NODE_ENV === 'development';

// 10. 设置全局日志级别
if (process.env.LOG_LEVEL && ['debug', 'info', 'warn', 'error'].includes(process.env.LOG_LEVEL.toLowerCase())) {
    setGlobalLogLevel(process.env.LOG_LEVEL.toLowerCase());
} else if (isDev) {
    setGlobalLogLevel('debug');
} else {
    setGlobalLogLevel('info');
}

// 11. 中间件配置
// 初始化 SSE 管理器
const sseManager = SSEManager.getInstance();
logger.info('🔄 SSE 管理器已初始化');
logger.info('💓 心跳检查将通过定时任务管理器执行');

// 使用请求ID中间件（确保在其他中间件之前使用）
app.use(requestIdMiddleware);
logger.info('✅ 请求ID中间件已启用，为每个请求生成correlation_id');

// 12. 日志中间件配置
if (isDev) {
    app.use(requestLogger);
    logger.info('🚀 开发环境已启动，启用详细日志记录');
}

// 13. 静态资源配置
app.use(express.static('public'));
app.use('/uploads', express.static(__dirname + "/data/uploads"));

// 14. 解析器配置
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' }));

// 15. CORS配置
app.use(cors({
    origin: ['http://localhost:8080', 'http://127.0.0.1:8080', 'https://www.liyq666.top','http://localhost:8888'], // 允许的源
    credentials: true, // 允许携带凭证
    methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'], // 允许的HTTP方法
    allowedHeaders: ['Origin', 'Content-Type', 'Authorization', 'Accept', 'X-Client-Page', 'X-Client-Id'] // 允许的请求头
}));

// 16. 会话配置（目前注释掉）
// app.use(session({
//     secret: process.env.SESSION_SECRET || devConfig.session.secret,
//     resave: devConfig.session.resave,
//     saveUninitialized: devConfig.session.saveUninitialized,
//     cookie: {
//         secure: devConfig.session.cookie.secure,
//         maxAge: devConfig.session.cookie.maxAge
//     }
// }));

// 17. 路由配置
app.use('/', require('./src/routes'));

// 初始化基础设施客户端
initializeDbPool();
if (cacheType === 'redis' && config.redis?.host && config.redis?.port) {
  initializeRedisClient();
}

// 18. 健康检查路由
app.get('/health', async (req, res) => {
    try {
        // 检查数据库连接
        const isConnected = await checkDatabaseConnection();
        logger.info('数据库连接状态:', isConnected ? 'connected' : 'disconnected');
        
        // 检查Redis连接
        const redisStatus = await performRedisHealthCheck();
        logger.info('Redis连接状态:', redisStatus ? 'connected' : 'disconnected');
        
        res.status(200).json({
            status: 'healthy',
            timestamp: new Date().toISOString(),
            database: isConnected ? 'connected' : 'disconnected',
            redis: redisStatus ? 'connected' : 'disconnected',
            cache: cacheType === 'redis' ? 'Redis' : '内存'
        });
    } catch (error) {
        logger.error('健康检查失败:', { error });
        res.status(503).json({
            status: 'unhealthy',
            timestamp: new Date().toISOString(),
            error: error
        });
    }
});

// 19. 404 处理
app.use((req, res, next) => {
    serverError(req, res, '接口不存在');
});

// 20. 错误处理中间件
app.use(errorLogger);

// 21. 全局错误捕获
app.use((err, req, res, next) => {
    logger.error('未处理的错误', { stack: err.stack });
    serverError(req, res, '服务器内部错误');
});

// 22. 定时任务初始化函数
const initScheduledTasks = async () => {
    logger.info('⏰ 初始化定时任务...');

    try {
        const cleanedCount = await authController.cleanupExpiredTokens();
        if (isDev && cleanedCount > 0) {
            logger.info(`🚀 启动时清理了 ${cleanedCount} 个过期token`);
        }
    } catch (error) {
        logger.error('启动时清理失败', { error });
    }

    scheduler.addFromConfig('databaseHealthCheck', async () => {
        try {
            const ok = await checkDatabaseConnection();
            if (!ok) logger.warn('⚠️ 数据库健康检查失败，请检查数据库服务状态');
        } catch (error) {
            logger.error('数据库健康检查出错:', { error: error });
        }
    });

    if (cacheType === 'redis' && config.redis?.host && config.redis?.port) {
        scheduler.addFromConfig('redisHealthCheck', async () => {
            try {
                const connected = await performRedisHealthCheck();
                if (!connected) {
                    logger.debug('Redis连接不可用，确认已切换到内存缓存');
                }
            } catch (error) {
                if (isDev) {
                    logger.debug('Redis健康检查出错(已预期)，系统应自动使用内存缓存:', { error: error });
                }
            }
        });
    }

    scheduler.addFromConfig('sseHeartbeat', () => {
        sseManager.checkHeartbeats();
        sseManager.cleanupInactiveConnections();
    });

    scheduler.addFromConfig('tokenCleanup', async () => {
        try {
            await authController.cleanupExpiredTokens();
        } catch (error) {
            logger.error('❌ Token清理任务失败', { error });
        }
    });

    logger.info('✅ 所有定时任务初始化完成');
};

// 24. 服务器配置和启动
logger.info('🚀 服务器正在启动...');

// 配置服务器参数
const envconfig = {
    port: process.env.PORT || 8888 ,
    host: process.env.HOST || '0.0.0.0',
    environment: process.env.NODE_ENV || 'development'
};

// 启动服务器
app.listen(envconfig.port, envconfig.host, async () => {
    // 打印启动信息
    logger.info('==========================================');
    logger.info(`🚀 服务器已成功启动`);
    logger.info(`📍 监听地址: http://${envconfig.host}:${envconfig.port}`);
    logger.info(`🌍 运行环境: ${envconfig.environment}`);
    logger.info(`💾 缓存类型: ${cacheType === 'redis' ? 'Redis' : '内存'}`);
    logger.info('==========================================');

    // 步骤1: 检查核心服务连接
    try {
        // 检测数据库连接
        const dbConnected = await checkDatabaseConnection();
        if (!dbConnected) {
            logger.error('⚠️ 数据库连接失败，服务可能无法正常工作');
            // 注意：这里不退出进程，允许服务继续启动，但记录警告
        }
        
        // 检测Redis连接
        const redisConnected = await performRedisHealthCheck();
        if (!redisConnected) {
            logger.error('⚠️ Redis连接失败，缓存相关功能可能无法正常工作');
        }
    } catch (error) {
        logger.error('❌ 服务连接检查失败:', { error});
    }

    // 步骤2: 初始化定时任务系统
    await initScheduledTasks();

    // 步骤3: 序列号表无需预初始化，首次使用时懒创建+原子递增

    // 步骤4: 显示环境特定信息
    if (isDev) {
        logger.info('🔧 开发环境特性:');
        logger.info('   - 详细日志记录已启用');
        logger.info('   - 验证码调试信息已启用');
        logger.info('   - 性能监控已启用');
        logger.info(`   - 验证码过期时间: ${config.captcha.expireTime / 1000}秒`);
        logger.info(`   - 验证码清理间隔: ${config.captcha.cleanupInterval / 1000}秒`);
        logger.info('   - Token清理间隔: 5分钟');
    } else {
        logger.info('🏭 生产环境特性:');
        logger.info('   - Token清理间隔: 1小时');
        logger.info('   - 性能监控已启用');
    }

    logger.info('✅ 服务初始化完成，可以开始处理请求');
});

// 23. 优雅关闭处理
async function gracefulShutdown(signal) {
    logger.info(`🛑 接收到${signal}信号，正在关闭服务器...`);

    try {
        // 步骤1: 关闭所有定时任务
        scheduler.shutdown();
        logger.info('✅ 定时任务调度器已关闭');

        // 步骤2: 关闭数据库连接池
        await closeDbPool();
        logger.info('✅ 数据库连接池已关闭');

        // 步骤3: 关闭Redis连接
        await closeRedis();

        logger.info('✅ 服务器已优雅关闭');
        process.exit(0);
    } catch (error) {
        logger.error('❌ 关闭过程中发生错误:', { error: error });
        process.exit(1);
    }
}

// 注册信号处理器
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));